#pragma once

#include <iostream>
#include <string>
#include <unordered_map>
#include <functional>
#include "TcpServer.hpp"	// 网络
#include "HttpProtocol.hpp" // 协议

using namespace TcpServerModule;

using http_handler_t = std::function<void(HttpRequest&,HttpResponse&)>;

class HttpServer
{
public:
	HttpServer(int port)
		: _tsvr(std::make_unique<TcpServer>(port))
	{
	}

	void Register(std::string funcname,http_handler_t func)
	{
		_route[funcname] = func;
	}

	bool SafeCheck(const std::string& service)
	{
		auto iter = _route.find(service);
		return iter != _route.end();
	}

	void Start()
	{
		_tsvr->InitServer([this](SockPtr sockfd, InetAddr client)
						  { return this->HandlerHttpRequest(sockfd, client); });
		_tsvr->Loop();
	}

	// 这就是我们处理http的入口
	bool HandlerHttpRequest(SockPtr sockfd, InetAddr client)
	{
		LOG(LogLevel::DEBUG) << "get a new client" << sockfd->Fd() << "addr info: " << client.Addr();
		std::string http_request;
		sockfd->Recv(&http_request); // 读

		// std::cout << http_request << std::endl; // 字节流的请求

		// 读取请求，对请求进行分析处理-->文本处理
		// 1.读取请求的完整性  2.完整http反序列化，http response序列化

		// 1.demo1: 直接返回一个固定内容
		// std::string status_line = "HTTP/1.1 200 OK" + Sep + BlankLine;

		// 直接返回一个网页
		// std::string body = "<!DOCTYPE html>\
        //                     <html>\
        //                    <head>\
        //                    <meta charset = \"UTF-8\">\
        //                    <title> Hello World</title>\
        //                    </head>\
        //                    <body>\
        //                    <p> Hello World</ p>\
        //                    </body> </html>";

		// std::string httpresponse = status_line + body;
		// sockfd->Send(httpresponse);

		HttpRequest req;
		req.Deserilalize(http_request);
		HttpResponse resp;

		// 序列化之后，请求应该被分成两类  1.请求一般的静态资源  2.提交参数，携带参数，需要我们进行交互设置
		if (req.IsHasArgs()) // 是否携带参数
		{
			// 2.提交参数，携带参数，需要我们进行交互设置
			std::string service = req.Path();
			if(SafeCheck(service))
				_route[req.Path()](req,resp);
			else
				resp.Bulid(req); // 构建应答
		}
		else
		{
			resp.Bulid(req); // 构建应答
		}
		std::string resp_str;
		resp.Serialize(&resp_str); 

		sockfd->Send(resp_str);

		return true;
	}
	~HttpServer()
	{
	}

private:
	std::unique_ptr<TcpServer> _tsvr;
	std::unordered_map<std::string,http_handler_t> _route; // 功能路由
};